struct cdq_bit_t{ // CDQ套树状数组, 三维偏序, 如果无需离散化，需要修改，否则可能会T

struct FenwickTree{ // 树状数组

using value_type = long long int;
using vec_type = vector<value_type>;

int n;
vec_type c;

FenwickTree() = default;

static int lowbit(int x){return x & -x;}

void init(int nn){this->c.assign((this->n=nn) + 1, 0);}

void modify(int pos, value_type delta){
    for(int i=pos;i<=this->n;i+=lowbit(i)) this->c[i] += delta;
}

value_type query(int pos)const{
    value_type ans = 0;
    for(int i=pos;i;i-=lowbit(i)) ans += this->c[i];
    return ans;
}

value_type query(int s, int e)const{return this->query(e) - this->query(s - 1);}

}Bt;

using value_t = int;
using cmp_t = function<bool(value_t, value_t)>;

struct _t{
    value_t x;
	value_t y;
	value_t z;
	int pos;
};

int N;
vector<_t> A, B;
cmp_t cmp1, cmp2, cmp3;

void setCmp(cmp_t c1, cmp_t c2, cmp_t c3){
	cmp1 = c1; cmp2 = c2; cmp3 = c3;
}

void input(){
	cin >> N;
	A.assign(N, {});
	B.assign(N, {});
	int k = 0;
	for(auto & p : A) {
		cin >> p.x >> p.y >> p.z;
		p.pos = k++;
	} 
	return;
}

vector<int> Ans;
vector<value_t> W;

void run(){
    Ans.assign(N, 0);
	sort(A.begin(), A.end(), [this](const _t & a, const _t & b){
		if(a.x != b.x) return this->cmp1(a.x, b.x);		
		if(a.y != b.y) return this->cmp2(a.y, b.y);
		if(a.z != b.z) return this->cmp3(a.z, b.z);
		return a.pos < b.pos;
	});
	
	/// 对z坐标离散化
	W.clear(); W.reserve(N + 1);
	W.push_back(INT_MIN);
	for(const auto & p : A) W.emplace_back(p.z);
	W.push_back(INT_MAX);
	sort(W.begin(), W.end(), this->cmp3);
	W.erase(unique(W.begin(), W.end()), W.end());

	int n = W.size();
	Bt.init(n);

	CDQ(0, N - 1);
	return;
}

void CDQ(int s, int e){
	if(s >= e) return;

	int mid = (s + e) >> 1;
	CDQ(s, mid); CDQ(mid + 1, e);

    int u = s, v = mid + 1, t = s;
	while(u <= mid and v <= e){
        if(this->cmp2(A[u].y, A[v].y)){
            auto p = lower_bound(W.begin(), W.end(), A[u].z, this->cmp3) - W.begin();
			Bt.modify(p, 1);
			B[t++] = A[u++];
		}else{ // 为否时说明[s, u)的y全都比v.y要小
			auto p = lower_bound(W.begin(), W.end(), A[v].z, this->cmp3) - W.begin();
            Ans[A[v].pos] += Bt.query(p - 1); // Bt中是z也小的数量
			B[t++] = A[v++];
		}
	}
	while(u <= mid){
		auto p = lower_bound(W.begin(), W.end(), A[u].z, this->cmp3) - W.begin();
		Bt.modify(p, 1);      
		B[t++] = A[u++];  
	}
	while(v <= e){
		auto p = lower_bound(W.begin(), W.end(), A[v].z, this->cmp3) - W.begin();
		Ans[A[v].pos] += Bt.query(p - 1); 
		B[t++] = A[v++];
	}

	/// 清空树状数组
	for(int i=s;i<=mid;++i) {
		auto p = lower_bound(W.begin(), W.end(), A[i].z, this->cmp3) - W.begin();
		Bt.modify(p, -1);
	}

	copy(B.begin() + s, B.begin() + e + 1, A.begin() + s);
	return;
}

};